package com.yh.csx.crm.service.logic;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.yh.b2b.common.exception.CommonException;
import com.yh.b2b.mall.common.enums.BizError;
import com.yh.csx.crm.core.enums.ApprovalTypeEnum;
import com.yh.csx.crm.core.enums.SapSyncTypeEnum;
import com.yh.csx.crm.core.exception.BusinessException;
import com.yh.csx.crm.core.util.DateUtils;
import com.yh.csx.crm.core.util.SapUtils;
import com.yh.csx.crm.dao.CustomerCompanyExtMapper;
import com.yh.csx.crm.dao.CustomerMapper;
import com.yh.csx.crm.dao.CustomerSyncLogMapper;
import com.yh.csx.crm.dao.SysCustomerCategoryMapper;
import com.yh.csx.crm.po.Customer;
import com.yh.csx.crm.po.CustomerCompanyExt;
import com.yh.csx.crm.po.CustomerSyncLog;
import com.yh.csx.crm.service.vo.SAPResponse;
import com.yh.csx.crm.service.vo.SapCustomer;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import lombok.var;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author: chejiangyi
 * @create: 2019-02-28 14:49
 **/
@Slf4j
@Component
public class SapLogic {

    private static ExecutorService thread = Executors.newCachedThreadPool();
    private static ExecutorService task = Executors.newFixedThreadPool(5);
    @Autowired
    CustomerMapper customerMapper;
    @Autowired
    SysCustomerCategoryMapper sysCustomerCategoryMapper;
    @Autowired
    CustomerSyncLogMapper customerSyncLogMapper;
    @Autowired
    CustomerCompanyExtMapper customerCompanyExtMapper;

    public void create(Customer customer) {
        thread.submit(
                ()->{
                    try {
                        CustomerSyncLog customerSyncLog = new CustomerSyncLog();
                        customerSyncLog.setCustomerId(customer.getId());
                        customerSyncLog.setSyncType(SapSyncTypeEnum.CREATE.getCode());
                        customerSyncLog.setRemark(ApprovalTypeEnum.NEW.getName());
                        customerSyncLogMapper.insertSelective(customerSyncLog);

//                        val customer = customerMapper.selectByPrimaryKey(customerId);
//                        val category1 = sysCustomerCategoryMapper.selectByPrimaryKey(customer.getCustomerCategoryId());
                        SapCustomer data = new SapCustomer().init();
                        val header = data.getSheet().get(0).getHeader();
                        var item = data.getSheet().get(0).getItem().get(0);

                        String datetime = new SimpleDateFormat("yyyyMMddHHmmssSSS")
                                .format(new Date());
                        header.put("source", "CX");//数据来源(固定值)
                        header.put("fdNumber", "TGHT"+datetime+customer.getId()+"");//传入单号
                        header.put("fdCompanyCode", customer.getCompanyCode()+"");//公司代码
                        header.put("fd_33c413d24270e0", customer.getPaymentTerms()+"");//付款条件
                        header.put("fdCustomerName", customer.getCustomerName());//客户名称
                        header.put("fdTel", customer.getPhone());//电话号码
                        header.put("fdCheckName", customer.getInvoiceName());//开票名称
                        header.put("fdCustAddrss", "");//地址 add
                        header.put("fdTaxNumber",customer.getSocialCreditCode());//增值税号 add
                        header.put("fdCustProvince", customer.getRegionProvince());//省
                        header.put("fdCustCity", customer.getRegionCity());//市
                        header.put("fd_33c41d28429ab6", customer.getSaleRegion());//销售地区
                        header.put("fdCcLevel", customer.getCustomerLevel()+"");//信控级别
//                        header.put("fdCcAmount", customer.getCreditLimit()+"");//信控额度
                        if (Objects.nonNull(customer.getTempCreditLimit()) && customer.getTempCreditLimit().doubleValue() > 0 &&
                                DateUtils.belongCalendar(new Date(), customer.getTempBeginTime(), customer.getTempEndTime())) {
                            header.put("fdCcAmount", customer.getTempCreditLimit().add(customer.getCreditLimit()) + "");//信控额度
                        } else {
                            header.put("fdCcAmount", customer.getCreditLimit() + "");//信控额度
                        }
                        header.put("fdCcRange", customer.getCreditRange()+"");//信控范围
                        header.put("fd_link_name","");//门店名称 add
                        header.put("fdSaleRoad", customer.getFirstCategoryCode()+"");//二级分销渠道
                        header.put("fdCustomerFirst", customer.getSecondCategoryCode()+"");//一级客户性质
                        header.put("fdCustomerSecond", customer.getThirdCategoryCode()+"");//二级客户性质
                        header.put("fdInarea", customer.getSalesProvince()+"");//所属省区
                        header.put("distribution_channel", customer.getDistributionChannel());//分销渠道
                        header.put("sale_region", customer.getSaleRegion());//销售地区
                        item.put("fdContactName", customer.getCustomerName());//联系人名称1
                        item.put("fdContactTel", customer.getPhone());//联系人电话
                        item.put("fdSendAddress", customer.getAddressDetails());//送货地址
                        item.put("fdAccountNumber", customer.getBankAccountNumber());//银行账户
                        item.put("fdAccountName", customer.getBankAccountName());//银行户主
                        item.put("fd_30e07049b2fefe", customer.getBankNumber());//联行号

                        // 将SAP请求参数 先行存入日志
                        String url = SapUtils.sap_customer_url;             // SAP请求地址
                        String request_str = JSON.toJSONString(data);       // SAP请求参数
                        String userName =  SapUtils.sap_customer_user;      // SAP请求用户名
                        String password = SapUtils.sap_customer_password;   // SAP请求密码

                        StringBuilder sb = new StringBuilder();
                        sb.append("url:{").append(url).append("},")
                                .append("name:{").append(userName).append("},")
                                .append("pwd:{").append(password).append("},")
                                .append("param:{").append(request_str).append("},")
                                .append("hear:{").append(header).append("}");
                        String requestContent = sb.toString();
                        customerSyncLog.setSapRequest(requestContent);
                        customerSyncLogMapper.updateByPrimaryKeySelective(customerSyncLog); // 存入请求日志

                        var response = SapUtils.sendHttpPostAuth(url, request_str, userName, password, null);
                        log.info("彩食鲜团购传ECC接口add-返回结果：{}",response);
                        Optional.ofNullable(response).orElseThrow(() ->  new BusinessException(response));

                        if (!StringUtils.isEmpty(response)) {
//                            val j = JSON.parseObject(response, new TypeReference<HashMap<String, Object>>() {});
                            val j = JSON.parseObject(response, SAPResponse.class);
                            Optional.ofNullable(j.getKUNNR()).orElseThrow(() ->  new BusinessException(response));

                            val sapId = j.getKUNNR();
                            var update = new Customer();
                            update.setId(customer.getId());
                            update.setCustomerNumber(sapId);
                            update.setSyncFlag(true);
                            customerMapper.updateByPrimaryKeySelective(update);

                            if (j.getITEM().get(0).getFD_SYNC_STATUS().equals("0")) {
                                customerSyncLog.setStatus(true);
                            }

                            customerSyncLog.setCustomerNumber(sapId);
                            customerSyncLog.setSapResponse(response);
                            customerSyncLogMapper.updateByPrimaryKeySelective(customerSyncLog);
                        }
                    }
                    catch (Exception exp)
                    {
                        log.error("新建同步sap客户信息异常，customerId:"+customer.getId(),exp);
                    }
                }
        );

    }

    /**
     *
     * @param customer
     * @param type 修改类型，必填，1代表修改2代表扩公司
     */
    public void edit(Customer customer,Integer type) {

        thread.submit(() -> {
                    try {
                        CustomerSyncLog customerSyncLog = new CustomerSyncLog();
                        customerSyncLog.setCustomerId(customer.getId());
                        customerSyncLog.setSyncType(SapSyncTypeEnum.EDIT.getCode());
                        if (type.equals(2)) {
                            customerSyncLog.setRemark(ApprovalTypeEnum.EXT_COMPANY.getName());
                        } else {
                            customerSyncLog.setRemark("信控和其他信息修改");
                        }
                        customerSyncLogMapper.insertSelective(customerSyncLog);

//                        val customer = customerMapper.selectByPrimaryKey(customerId);
                        SapCustomer data = new SapCustomer().init();
                        val header = data.getSheet().get(0).getHeader();
                        var item = data.getSheet().get(0).getItem().get(0);
                        header.put("type", type+"");//修改类型
                        header.put("source", "CX");//数据来源(固定值)
                        header.put("customer_number", customer.getCustomerNumber());//客户编号
                        if (type.equals(2)) {
//                            val customerCompanyExts = customerCompanyExtMapper.selectExistQuery(customer.getId(), null);
                            header.put("company_code", customer.getCompanyCode()+"");//公司代码
                            header.put("payment_terms", customer.getPaymentTerms()+"");//付款条件
                            header.put("sale_organization", customer.getCompanyCode());//销售组织
                            header.put("credit_range", customer.getCompanyCode());//信控范围
                            header.put("customer_level", customer.getCustomerLevel()+""); //信控级别
                            header.put("credit_limit", customer.getCreditLimit()+"");//信控额度
                        }
                        header.put("customer_name", customer.getCustomerName());//客户名称
                        header.put("phone", customer.getPhone());//电话号码
                        header.put("invoice_title", customer.getInvoiceName());//开票名称
                        header.put("social_credit_code", customer.getSocialCreditCode());//增值税登记号
                        header.put("region_province", customer.getRegionProvince());//省
                        header.put("region_city", customer.getRegionCity());//市
                        header.put("channel_second_code", customer.getFirstCategoryCode() + "");//二级分销渠道
                        header.put("category_code1", customer.getSecondCategoryCode());//一级客户性质
                        header.put("customer_code2", customer.getThirdCategoryCode());//二级客户性质
                        header.put("sales_province_id", customer.getSalesProvince() + "");//所属省区
                        if (type.equals(1)) {
                            header.put("company_code", customer.getCompanyCode() + "");//公司代码
                            header.put("payment_terms", customer.getPaymentTerms() + "");//付款条件
                            header.put("sale_organization", customer.getCompanyCode());//销售组织
                            header.put("credit_range", customer.getCompanyCode());//信控范围
                            header.put("customer_level", customer.getCustomerLevel() + ""); //信控级别
//                            header.put("credit_limit", customer.getCreditLimit() + "");//信控额度
                            if (Objects.nonNull(customer.getTempCreditLimit()) && customer.getTempCreditLimit().doubleValue() > 0 &&
                                    DateUtils.belongCalendar(new Date(), customer.getTempBeginTime(), customer.getTempEndTime())) {
                                header.put("credit_limit", customer.getTempCreditLimit().add(customer.getCreditLimit()) + "");//信控额度
                            } else {
                                header.put("credit_limit", customer.getCreditLimit() + "");//信控额度
                            }
                        }

                        item.put("name", customer.getCustomerName());//联系人名称1
                        item.put("phone1", customer.getPhone());//联系人电话
                        item.put("bank_account_number", customer.getBankAccountNumber());//银行账户
                        item.put("bank_account_name", customer.getBankAccountName());//银行户主
                        item.put("bank_number", customer.getBankNumber());//联行号

                        header.put("distribution_channel", customer.getDistributionChannel());//分销渠道
                        header.put("sale_region", customer.getSaleRegion());//销售地区

                        // 将SAP请求参数 先行存入日志
                        String url = SapUtils.sap_update_customer_url;             // SAP请求地址
                        String request_str = JSON.toJSONString(data);       // SAP请求参数
                        String userName =  SapUtils.sap_customer_user;      // SAP请求用户名
                        String password = SapUtils.sap_customer_password;   // SAP请求密码

                        StringBuilder sb = new StringBuilder();
                        sb.append("url:{").append(url).append("},")
                                .append("name:{").append(userName).append("},")
                                .append("pwd:{").append(password).append("},")
                                .append("param:{").append(request_str).append("},")
                                .append("hear:{").append(header).append("}");
                        String requestContent = sb.toString();
                        customerSyncLog.setSapRequest(requestContent);
                        customerSyncLogMapper.updateByPrimaryKeySelective(customerSyncLog); // 存入请求日志

                        var response = SapUtils.sendHttpPostAuth(url, request_str, userName, password, null);
                        log.info("彩食鲜团购传ECC接口update-返回结果：{}",response);
                        Optional.ofNullable(response).orElseThrow(() ->  new BusinessException(response));

                        if (!StringUtils.isEmpty(response)) {
//                            val j = JSON.parseObject(response, new TypeReference<HashMap<String, Object>>(){});
                            val j = JSON.parseObject(response, SAPResponse.class);

                            if (j.getITEM().get(0).getFD_SYNC_STATUS().equals("0")) {
                                customerSyncLog.setStatus(true);
                            }
                            val sapId = j.getKUNNR(); // 得到客户号ID
                            customerSyncLog.setCustomerNumber(sapId);
                            customerSyncLog.setSapResponse(response);
                            customerSyncLogMapper.updateByPrimaryKeySelective(customerSyncLog);
                        }

                    }
                    catch (Exception exp)
                    {
                        log.error("编辑同步sap客户信息异常，customerId:"+customer.getId(),exp);
                    }
                }
        );
    }

    public void run()
    {
        task.submit(()->{
            while (true)
            {
                try
                {
                    ///todo 从sap下发更新，暂不做
                    //customerMapper.u
                }
                catch (Exception exp)
                {
                    log.error("扫描sap客户更新任务出错",exp.getMessage());
                }
                try{ Thread.sleep(1000*5);}catch (Exception e){}
            }
        } );
    }
}
